<?php

namespace App\Models;

use Cache;

class GoodsCategory extends BaseModel
{
    protected $table = "goods_category";

    const GOODS_CATEGORY_DATA = 'GOODS_CATEGORY_DATA';
    const GOODS_CATEGORY_ALL_DATA = 'GOODS_CATEGORY_ALL_DATA';

    public $primaryCategoryIds = [1,3,5,6,7];

    protected $rules = [
        'title' => 'required|between:1,15',
    ];

    protected $message = [
        'title.required' => '分类名称必须填写',
        'title.between' => '分类名称不合法必须1-15位字符',
    ];

    /**
     * 获取分类详细信息
     * @param  milit $id 分类ID或标识
     * @param  boolean $field 查询字段
     * @return array     分类信息
     */
    public function getInfo($id)
    {
        $list = $this->getALLCache();
        /* 获取分类信息 */
        if (is_numeric($id)) { //通过ID查询
            return $list[$id];
        }
        foreach ($list as $k => $v) {
            if ($v['title'] == $id) {
                return $v;
            }
        }
        return false;
    }


    /**
     * 获取分类树，指定分类则返回指定分类极其子分类，不指定则返回所有分类树
     * @param  integer $id 分类ID
     * @param  string $field 查询字段
     * @return array          分类树
     */
    public function getTree($id = 0, $field = '*')
    {
        /* 获取当前分类信息 */
        if ($id) {
            $info = $this->getInfo($id);
            $id = $info['id'];
        }
        $list = $this->getCache();
        $list = list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_', $root = $id);

        /* 获取返回数据 */
        if (isset($info)) { //指定分类则返回当前分类极其子分类
            $info['_'] = $list;
        } else { //否则返回所有分类
            $info = $list;
        }

        return $info;
    }

    /**
     * 获取配置列表
     * @return array 配置数组
     */
    public function getCache()
    {
        $res = Cache::get(self::GOODS_CATEGORY_DATA);
        if (!$res) {
            $where['status'] = ['>', -1];
            $res = $this->_getList($where, '*', ['sort' => 'asc'])->toArray();
            Cache::forever(self::GOODS_CATEGORY_DATA, $res);
        }
        return $res;
    }

    /**
     * 获取配置列表
     * @return array 配置数组
     */
    public function getALLCache()
    {
        $category = Cache::get(self::GOODS_CATEGORY_ALL_DATA);
        if (!$category) {
            $category = $this->_getList();
            if ($category) {
                $res = $category->toArray();
                $category = [];
                foreach ($res as $v) {
                    $category[$v['id']] = $v;
                }
            }
            Cache::forever(self::GOODS_CATEGORY_ALL_DATA, $category);
        }
        return $category;
    }

    public function generate()
    {
        Cache::forget(self::GOODS_CATEGORY_ALL_DATA);
        Cache::forget(self::GOODS_CATEGORY_DATA);
    }

    public function checkParentCategory()
    {
        if (request('pid')) {
            /* 获取上级分类信息 */
            $category = $this->getInfo(request('pid'));
            if (!($category && 1 == $category['status'])) {
                $this->error = '指定的上级分类不存在或被禁用！';
                return false;
            }
            return $category;
        }
        return true;
    }

    public function getCategoryTree()
    {
        $where['status'] = 1;
        $category = $this->_getList($where)->toArray();
        $category = childTree($category, 0, 'id', 'pid');
        $category = array_merge([0 => ['id' => 0, 'title' => '顶级菜单', 'prefix' => '']], $category);
        return $category;
    }

    public function getParentCategory()
    {
        $key = 'goods_parent_category';
        if ($this->redis->exists($key)) {
            return unserialize($this->redis->get($key));
        }
        $res = $this->_getList(['pid'=>0],'id,title',['sort'=>'asc'])->toArray();
        $this->redis->set($key,serialize($res));;
        return $res;
    }

    public function operate($type)
    {
        $to = request('to');
        $from = request('from');
        $operate = $type == 'move' ? '移动' : ($type == 'merge' ? '合并' : '');
        if (!$operate) {
            $this->error = '参数错误！';
            return false;
        }
        if ($type == 'move') {
            $res = $this->_update(['id' => $from], ['pid' => $to]);
            if (!$res) {
                $this->error = '分类移动失败！';
                return false;
            }
        }
        if ($type == 'merge') {
            $goods = new Goods();
            $goodsList = $goods->_getList(['category_id' => $from])->toArray();
            if (!empty($goodsList)) {
                $res = $goods->_update(['category_id' => $from], ['category_id' => $to]);
                if (!$res) {
                    $this->error = '合并分类失败！';
                    return false;
                }
            }
            //删除被合并的分类
            $this->_del(['id' => $from]);
        }
        $this->generate();
        //记录行为
        action_log('update_goods_category', 'goods_category', $from);
        return '分类' . $operate . '成功！';
    }

    public function addOrUpdate()
    {
        if (!$this->checkParentCategory()) {
            return false;
        }
        $data['title'] = trim(request('title'));
        if (request('id')) {
            $data['id'] = trim(request('id'));
        }
        if (!$this->_validate($data)) {
            return false;
        }
        $data['title'] = request('title');
        if (request()->has('pid')) {
        $data['pid'] = request('pid');
        }
        if (request()->has('status')) {
            $data['status'] = trim(request('status', 1));
        }
        if (request()->has('sort')) {
            $data['sort'] = trim(request('sort', 0));
        }
        if (request()->has('allow_publish')) {
            $data['allow_publish'] = trim(request('allow_publish', 1));
        }
        $res = $this->_save($data);
        if ($res) {
            $id = isset($data['id']) ? $data['id'] : $this->id;
            //记录行为
            action_log('update_goods_category', 'goods_category', $id);
            $this->generate();
        }
        return $res;
    }

    public function del()
    {
        $id = request('id');
        if (!$id) {
            $this->error = '请选择要操作的数据!';
            return false;
        }
        $child = $this->_getList(['pid' => $id])->toArray();
        if (!empty($child)) {
            $this->error = '请先删除该分类下的子分类';
            return false;
        }
        $res = $this->_del(['id' => $id]);
        if (!$res) {
            $this->error = '删除分类失败!';
            return false;
        }
        //记录行为
        action_log('update_goods_category', 'category', $id);
        $this->generate();
        return '删除分类成功';
    }

}
